﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using PositionUtils;
using System.Diagnostics;

namespace Tanks
{
    abstract class ITank : IFieldObject
    {        
        protected float                           speed = 0;               //скорость танка
        protected float                             currentSpeed = 0;
        protected float                           rotationSpeed = 0.04f;   //скорость поворота
        protected float                             currentRotationSpeed = 0.04f;
        protected int                             health = 0;              //макс здоровье
        protected int                             currentHealth = 0;       //текущее здоровье
        protected Vector2[]                       boards = new Vector2[4]; //границы танка(4 угла)
        protected KeyboardSettings                keySetting;              //настройки управления
        protected float                           bufRotation;             //угол поворота, после нажатия клавишы
        protected Microsoft.Xna.Framework.Vector2 bufPosition;             //позиция после нажатия клавишы       
        bool isDown = false;
        int fireDelay = 2000;
        int fireCount = 0;
        KeyboardState keyboard;        
        int timeDead = 0;

        public ITank(Texture2D _tex, Texture2D _texDead, Game1 game, KeyboardSettings keySetting)
            : base(game, new PropertiesObject(), _tex)
        {
            Properties.IsFon = false;
            Properties.IsTank = true;
            this.keySetting = keySetting;
            textureDead = _texDead;
        }
        public override void Update(GameTime gameTime)
        {            
            Properties.WasActive = false;
            keyboard = Keyboard.GetState();
            isDown = false;
            if (!Properties.IsDead)
            {
                if (fireCount <= 0)
                {
                    if (keyboard.IsKeyDown(keySetting.Shot))
                    {
                        this.Shoting();
                        fireCount = fireDelay;
                    }
                }
                else
                {
                    fireCount -= gameTime.ElapsedGameTime.Milliseconds;
                }
                bufRotation = rotation;
                bufPosition.X = position.X;
                bufPosition.Y = position.Y;

                if (keyboard.IsKeyDown(keySetting.Down))
                {
                    bufPosition.X += (float)(currentSpeed * Math.Cos(rotation));
                    bufPosition.Y += (float)(currentSpeed * Math.Sin(rotation));
                    isDown = true;
                    Properties.WasActive = true;
                }
                if (keyboard.IsKeyDown(keySetting.Up))
                {
                    bufPosition.X += -(float)(currentSpeed * Math.Cos(rotation));
                    bufPosition.Y += -(float)(currentSpeed * Math.Sin(rotation));
                    isDown = false;
                    Properties.WasActive = true;
                }
                if (keyboard.IsKeyDown(keySetting.Left))
                {
                    if (isDown == true)
                        bufRotation += currentRotationSpeed;
                    else
                        bufRotation += -currentRotationSpeed;
                    Properties.WasActive = true;
                }
                if (keyboard.IsKeyDown(keySetting.Right))
                {
                    if (isDown == true)
                        bufRotation += -currentRotationSpeed;
                    else
                        bufRotation += currentRotationSpeed;
                    Properties.WasActive = true;
                }


                boards = mPositionUtils.computeBoards(bufPosition, bufRotation, texture.Height, texture.Width);
                //проверка на выход за границы игрового поля
                if (!checkBoards(position, bufRotation))
                {
                    bufRotation = rotation;
                }
                if (!checkBoards(bufPosition, rotation))
                {

                    bufPosition.X = position.X;
                    bufPosition.Y = position.Y;
                }
                boards = mPositionUtils.computeBoards(bufPosition, bufRotation, texture.Height, texture.Width);
                currentSpeed = speed;
                currentRotationSpeed = rotationSpeed;
                
            }
            else
            {
                timeDead += gameTime.ElapsedGameTime.Milliseconds;
                if (timeDead > 1500) game.DeleteObject(this);
            }
            
        }
        public override void      Draw()
        {           
            game.SpriteBatch.Draw(texture, position, null, Color.White, rotation,
                    new Vector2(texture.Width / 2, texture.Height / 2), 1.0f, SpriteEffects.None, 0);

            game.SpriteBatch.Draw(Resources.FullHP, position,
                new Rectangle(0, 0, Resources.FullHP.Width, (int)(((double)currentHealth / (double)health) * Resources.FullHP.Height)),
                Color.White, rotation + 3.14f, new Vector2(texture.Width / 2 - 4, Resources.FullHP.Height / 2), 1.0f, SpriteEffects.None, 0);

            game.SpriteBatch.Draw(Resources.LowHP, position,
                new Rectangle(0, 0, Resources.LowHP.Width, Resources.LowHP.Height - (int)(((double)currentHealth / (double)health) * Resources.LowHP.Height)),
                Color.White, rotation, new Vector2(-texture.Width / 2 + Resources.LowHP.Width + 4, Resources.LowHP.Height / 2), 1.0f, SpriteEffects.None, 0);
        }
        public override Vector2   getActualPosition()
        {
            return bufPosition;
        }
        public override float     getActualRotation()
        {
            return bufRotation;
        }
        public override Vector2[] getActualBoards()
        {
            return mPositionUtils.computeBoards(position, rotation, texture.Height, texture.Width);
        }
        public override Vector2[] getBoards()
        {
            return boards;
        }
        public override void      collisionNotFounded()
        {            
            position = bufPosition;
            rotation = bufRotation;
        }
        public override void      collisionRotNotFounded()
        {
            rotation = bufRotation;
        }
        private bool checkBoards(Vector2 newPosition, float newRotation)
        {
            boards = mPositionUtils.computeBoards(newPosition, newRotation, texture.Height, texture.Width);
            for (int i = 0; i < boards.Length; i++)
            {                

                if (boards[i].X <= 0 || boards[i].X >= game.width ||
                    boards[i].Y <= 0 || boards[i].Y >= game.heigth)

                    return false;
            }
            return true;
        }
        abstract protected void Shoting();
        public override void collisionFounded(IFieldObject two)
        {
            if (two.Properties.IsShoot)
            {
                double distance = PositionUtils.mPositionUtils.computeDistance(position, two.Properties.StartPosition);
                if (distance < game.width / 3)
                {
                    currentHealth -= two.Properties.Damage;
                }
                else if (distance < game.width)
                {
                    double al = 1 - ((distance - game.width / 3) / (game.width - game.width / 3));
                    currentHealth -= (int)(two.Properties.Damage * al);
                }
                else
                {
                    currentHealth -= (int)(0.1 * two.Properties.Damage);
                }
            }
            if (two.Properties.IsSand)
            {
                currentSpeed = 2 * speed / 3;
                currentRotationSpeed = 2 * rotationSpeed / 3;
            }
           
            if (currentHealth <= 0)
            {
                if (!Properties.IsDead)
                {
                    Properties.IsDead = true;
                    this.texture = this.textureDead;
                    game.AddObject(new Animation(Resources.BOMBOM, game, new Vector2(this.position.X, this.position.Y), this.rotation, 20, 2.0f));
                    //game.DeleteObject(this);
                }
            }
        }
    }
}   
